{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Street network figure-ground diagrams\n",
    "\n",
    "Author: [Geoff Boeing](https://geoffboeing.com/)\n",
    "\n",
    "Use OSMnx to download square-mile city street networks and visualize them as figure-ground diagrams. Discussed in this [blog post](http://geoffboeing.com/2017/01/square-mile-street-network-visualization/).\n",
    "\n",
    "  - [Documentation](https://osmnx.readthedocs.io/)\n",
    "  - [Journal article and citation info](https://doi.org/10.1111/gean.70009)\n",
    "  - [Code repository](https://github.com/gboeing/osmnx)\n",
    "  - [Examples gallery](https://github.com/gboeing/osmnx-examples)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#!uv pip install --system --quiet osmnx[all]\n",
    "import osmnx as ox\n",
    "from IPython.display import Image\n",
    "\n",
    "ox.__version__"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Part I: create diagrams by passing in lat-long points"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_point(place, point, network_type=\"drive\", default_width=4):\n",
    "    img_folder = \"images\"\n",
    "    extension = \"png\"\n",
    "    dpi = 40\n",
    "    fp = f\"./{img_folder}/{place}.{extension}\"\n",
    "    G = ox.graph.graph_from_point(\n",
    "        point,\n",
    "        dist=1000,\n",
    "        network_type=network_type,\n",
    "        truncate_by_edge=True,\n",
    "    )\n",
    "    fig, ax = ox.plot.plot_figure_ground(\n",
    "        G=G,\n",
    "        dist=805,\n",
    "        default_width=default_width,\n",
    "        filepath=fp,\n",
    "        dpi=dpi,\n",
    "        save=True,\n",
    "        show=False,\n",
    "        close=True,\n",
    "    )\n",
    "    return fp"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fp = plot_point(\"sf\", (37.793897, -122.402189), \"all\")\n",
    "Image(fp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fp = plot_point(\"portland\", (45.517309, -122.682138))\n",
    "Image(fp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fp = plot_point(\"irvine\", (33.694981, -117.841375))\n",
    "Image(fp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fp = plot_point(\"rome\", (41.901336, 12.471831), \"all\", default_width=3.3)\n",
    "Image(fp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fp = plot_point(\"barcelona_gothic\", (41.382850, 2.174192), \"all\", default_width=3.3)\n",
    "Image(fp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fp = plot_point(\"manhattan\", (40.757920, -73.983393))\n",
    "Image(fp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fp = plot_point(\"los_angeles\", (34.047404, -118.253146))\n",
    "Image(fp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fp = plot_point(\"paris\", (48.873702, 2.294136), \"drive\", 3.3)\n",
    "Image(fp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fp = plot_point(\"dc\", (38.907919, -77.036552))\n",
    "Image(fp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fp = plot_point(\"dubai1\", (25.203143, 55.270007))\n",
    "Image(fp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fp = plot_point(\"dubai2\", (25.056565, 55.207924))\n",
    "Image(fp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fp = plot_point(\"shanghai\", (31.234696, 121.481170))\n",
    "Image(fp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fp = plot_point(\"osaka\", (34.694834, 135.484761), \"drive\", 2)\n",
    "Image(fp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fp = plot_point(\"boston\", (42.362084, -71.057267), \"drive\", 3.3)\n",
    "Image(fp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fp = plot_point(\"sacramento\", (38.587193, -121.372872), \"drive\", 5)\n",
    "Image(fp)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Part II: Create diagrams for any city, by just passing in a place name"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_place(place, network_type=\"drive\", default_width=4):\n",
    "    img_folder = \"images\"\n",
    "    extension = \"png\"\n",
    "    dpi = 40\n",
    "    fp = f\"./{img_folder}/{place}.{extension}\"\n",
    "    G = ox.graph.graph_from_address(\n",
    "        place,\n",
    "        dist=1000,\n",
    "        network_type=network_type,\n",
    "        truncate_by_edge=True,\n",
    "    )\n",
    "    fig, ax = ox.plot.plot_figure_ground(\n",
    "        G=G,\n",
    "        dist=805,\n",
    "        default_width=default_width,\n",
    "        filepath=fp,\n",
    "        dpi=dpi,\n",
    "        save=True,\n",
    "        show=False,\n",
    "        close=True,\n",
    "    )\n",
    "    return fp"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fp = plot_place(\"Atlanta, Georgia, USA\")\n",
    "Image(fp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fp = plot_place(\"Denver, Colorado, USA\")\n",
    "Image(fp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fp = plot_place(\"Sao Chingcha, Bangkok, Thailand\", \"drive\", 2)\n",
    "Image(fp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fp = plot_place(\"Medina of Tunis, Tunisia\", \"all\", 3)\n",
    "Image(fp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fp = plot_place(\"Times Square, New York, NY, USA\")\n",
    "Image(fp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fp = plot_place(\"East Village, New York, NY, USA\")\n",
    "Image(fp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fp = plot_place(\"Charlotte, North Carolina, USA\")\n",
    "Image(fp)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Part III: Configure street width pixels\n",
    "\n",
    "OSMnx uses the `highway` OSM tag to ascribe street widths, in pixels. You can pass in a dictionary of street widths to override the default values. Any street type that does not appear as a key in the street widths dict falls back onto the `default_width` value."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "street_widths = {\n",
    "    \"footway\": 0.5,\n",
    "    \"steps\": 0.5,\n",
    "    \"pedestrian\": 0.5,\n",
    "    \"path\": 0.5,\n",
    "    \"track\": 0.5,\n",
    "    \"service\": 2,\n",
    "    \"residential\": 3,\n",
    "    \"primary\": 5,\n",
    "    \"motorway\": 6,\n",
    "}\n",
    "point = (37.793897, -122.402189)\n",
    "fp = \"./images/sf_custom.png\"\n",
    "G = ox.graph.graph_from_point(point, dist=1000, network_type=\"all\", truncate_by_edge=True)\n",
    "fig, ax = ox.plot.plot_figure_ground(\n",
    "    G=G,\n",
    "    filepath=fp,\n",
    "    street_widths=street_widths,\n",
    "    default_width=4,\n",
    "    dpi=40,\n",
    "    save=True,\n",
    "    show=False,\n",
    "    close=True,\n",
    ")\n",
    "Image(fp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
